using B.S.XZYData.ErrorCode;
using B.S.XZYData.Infrastructure;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using SqlSugar;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;

namespace B.S.XZYData.Api.Read.Controllers
{
    /// <summary>
    /// 大屏仪表板数据控制器
    /// </summary>
    [ApiController]
    [Route("api/[controller]/[action]")]
    public class DashboardController : ControllerBase
    {
        private readonly MyDbContext _dbContext;

        public DashboardController(MyDbContext dbContext)
        {
            _dbContext = dbContext;
        }

        /// <summary>
        /// 获取不良品率统计
        /// </summary>
        /// <param name="days">统计天数，默认7天</param>
        /// <returns>不良品率数据</returns>
        [HttpGet]
        public async Task<ApiResult<DefectiveRateDto>> GetDefectiveRate([FromQuery] int days = 7)
        {
            try
            {
                var startDate = DateTime.Now.AddDays(-days).Date;
                var endDate = DateTime.Now.Date.AddDays(1);

                // 从报工表中统计不良品数据
                var workReports = await _dbContext.WorkReport
                    .Where(wr => !wr.IsDeleted && wr.CreateTime >= startDate && wr.CreateTime < endDate)
                    .ToListAsync();

                var totalProduced = workReports.Sum(wr => wr.GoodQty + wr.DefectiveQty);
                var totalDefective = workReports.Sum(wr => wr.DefectiveQty);
                var defectiveRate = totalProduced > 0 ? Math.Round((decimal)totalDefective / totalProduced * 100, 2) : 0;

                var result = new DefectiveRateDto
                {
                    TotalDefective = totalDefective,
                    TotalProduced = totalProduced,
                    DefectiveRate = defectiveRate,
                    DateRange = $"最近{days}天"
                };

                return ApiResult<DefectiveRateDto>.Success(result);
            }
            catch (Exception ex)
            {
                return ApiResult<DefectiveRateDto>.Error($"获取不良品率统计失败: {ex.Message}");
            }
        }

        /// <summary>
        /// 获取不良品分布Top排名
        /// </summary>
        /// <param name="days">统计天数，默认30天</param>
        /// <param name="top">Top数量，默认10</param>
        /// <returns>不良品分布排名</returns>
        [HttpGet]
        public async Task<ApiResult<List<DefectiveItemRankDto>>> GetDefectiveItemRank(
            [FromQuery] int days = 30, 
            [FromQuery] int top = 10)
        {
            try
            {
                var startDate = DateTime.Now.AddDays(-days).Date;
                var endDate = DateTime.Now.Date.AddDays(1);

                // 从报工表的不良品项中统计
                var workReportData = await _dbContext.WorkReport
                    .Where(wr => !wr.IsDeleted && wr.CreateTime >= startDate && wr.CreateTime < endDate && wr.DefectiveQty > 0)
                    .ToListAsync();

                // 由于没有具体的不良品项分类，我们按产品名称来统计不良品分布
                var defectiveDistributions = workReportData
                    .GroupBy(wr => new { ProductCode = wr.ProductCode ?? "未知产品", ProductName = wr.ProductName ?? "未知产品" })
                    .Select(g => new DefectiveItemRankDto
                    {
                        DefectiveItemCode = g.Key.ProductCode,
                        DefectiveItemName = g.Key.ProductName,
                        TotalQuantity = g.Sum(x => x.DefectiveQty),
                        AvgPercentage = g.Sum(x => x.ReportQty) > 0 ? 
                            Math.Round((decimal)g.Sum(x => x.DefectiveQty) / g.Sum(x => x.ReportQty) * 100, 2) : 0
                    })
                    .OrderByDescending(x => x.TotalQuantity)
                    .Take(top)
                    .ToList();

                return ApiResult<List<DefectiveItemRankDto>>.Success(defectiveDistributions);
            }
            catch (Exception ex)
            {
                return ApiResult<List<DefectiveItemRankDto>>.Error($"获取不良品分布排名失败: {ex.Message}");
            }
        }

        /// <summary>
        /// 获取员工绩效Top5
        /// </summary>
        /// <param name="days">统计天数，默认30天</param>
        /// <returns>员工绩效排名</returns>
        [HttpGet]
        public async Task<ApiResult<List<EmployeePerformanceDto>>> GetEmployeePerformance([FromQuery] int days = 30)
        {
            try
            {
                var startDate = DateTime.Now.AddDays(-days).Date;
                var endDate = DateTime.Now.Date.AddDays(1);

                // 从报工表中统计员工绩效
                var workReportData = await _dbContext.WorkReport
                    .Where(wr => !wr.IsDeleted && wr.CreateTime >= startDate && wr.CreateTime < endDate)
                    .ToListAsync();

                var employeeStats = workReportData
                    .GroupBy(wr => wr.Producer)
                    .Select(g => new EmployeePerformanceDto
                    {
                        EmployeeName = g.Key,
                        TotalGoodQuantity = g.Sum(x => x.GoodQty),
                        TotalWorkTime = g.Sum(x => x.ReportMinutes),
                        ReportCount = g.Count(),
                        EfficiencyScore = Math.Round(g.Average(x => x.ActualEfficiency), 2)
                    })
                    .OrderByDescending(x => x.TotalGoodQuantity)
                    .Take(5)
                    .ToList();

                return ApiResult<List<EmployeePerformanceDto>>.Success(employeeStats);
            }
            catch (Exception ex)
            {
                return ApiResult<List<EmployeePerformanceDto>>.Error($"获取员工绩效失败: {ex.Message}");
            }
        }

        /// <summary>
        /// 获取生产统计汇总
        /// </summary>
        /// <param name="days">统计天数，默认30天</param>
        /// <returns>生产统计数据</returns>
        [HttpGet]
        public async Task<ApiResult<ProductionSummaryDto>> GetProductionSummary([FromQuery] int days = 30)
        {
            try
            {
                var startDate = DateTime.Now.AddDays(-days).Date;
                var endDate = DateTime.Now.Date.AddDays(1);

                // 从工单表和报工表统计生产数据
                var workOrders = await _dbContext.WorkOrderModel
                    .Where(wo => wo.CreateTime >= startDate && wo.CreateTime < endDate)
                    .ToListAsync();

                var workReports = await _dbContext.WorkReport
                    .Where(wr => !wr.IsDeleted && wr.CreateTime >= startDate && wr.CreateTime < endDate)
                    .ToListAsync();

                var totalGoodQuantity = workReports.Sum(wr => wr.GoodQty);
                var totalBadQuantity = workReports.Sum(wr => wr.DefectiveQty);
                var totalQuantity = totalGoodQuantity + totalBadQuantity;
                var goodRate = totalQuantity > 0 ? Math.Round((decimal)totalGoodQuantity / totalQuantity * 100, 2) : 0;

                var result = new ProductionSummaryDto
                {
                    TotalGoodQuantity = totalGoodQuantity,
                    TotalBadQuantity = totalBadQuantity,
                    GoodRate = goodRate,
                    TotalWorkOrders = workOrders.Count
                };

                return ApiResult<ProductionSummaryDto>.Success(result);
            }
            catch (Exception ex)
            {
                return ApiResult<ProductionSummaryDto>.Error($"获取生产统计汇总失败: {ex.Message}");
            }
        }

        /// <summary>
        /// 获取日生产明细数据
        /// </summary>
        /// <param name="days">统计天数，默认7天</param>
        /// <returns>日生产明细</returns>
        [HttpGet]
        public async Task<ApiResult<List<DailyProductionDto>>> GetDailyProduction([FromQuery] int days = 7)
        {
            try
            {
                var startDate = DateTime.Now.AddDays(-days).Date;
                var endDate = DateTime.Now.Date.AddDays(1);

                // 按日期和产品分组统计
                var dailyWorkReports = await _dbContext.WorkReport
                    .Where(wr => !wr.IsDeleted && wr.CreateTime >= startDate && wr.CreateTime < endDate)
                    .ToListAsync();

                var dailyProduction = dailyWorkReports
                    .GroupBy(wr => new { 
                        Date = wr.CreateTime.Date, 
                        wr.ProductName 
                    })
                    .Select(g => new DailyProductionDto
                    {
                        ProductionDate = g.Key.Date,
                        ProductName = g.Key.ProductName ?? "未知产品",
                        PlannedQuantity = g.Sum(x => x.ReportQty), // 使用报工数量作为计划数量
                        GoodQuantity = g.Sum(x => x.GoodQty),
                        BadQuantity = g.Sum(x => x.DefectiveQty),
                        CompletionRate = g.Sum(x => x.ReportQty) > 0 ? 
                            Math.Round((decimal)g.Sum(x => x.GoodQty + x.DefectiveQty) / g.Sum(x => x.ReportQty) * 100, 2) : 0
                    })
                    .OrderByDescending(x => x.ProductionDate)
                    .ToList();

                return ApiResult<List<DailyProductionDto>>.Success(dailyProduction);
            }
            catch (Exception ex)
            {
                return ApiResult<List<DailyProductionDto>>.Error($"获取日生产明细失败: {ex.Message}");
            }
        }

        /// <summary>
        /// 获取工序计划数Top5
        /// </summary>
        /// <param name="days">统计天数，默认30天</param>
        /// <returns>工序计划排名</returns>
        [HttpGet]
        public async Task<ApiResult<List<ProcessPlanRankDto>>> GetProcessPlanRank([FromQuery] int days = 30)
        {
            try
            {
                var startDate = DateTime.Now.AddDays(-days).Date;
                var endDate = DateTime.Now.Date.AddDays(1);

                // 从工单工序表统计工序计划数
                var workOrderProcessData = await _dbContext.WorkOrderProcessModel
                    .Where(wop => wop.CreateTime >= startDate && wop.CreateTime < endDate)
                    .ToListAsync();

                var processPlanRank = workOrderProcessData
                    .GroupBy(wop => wop.ProcessName)
                    .Select(g => new ProcessPlanRankDto
                    {
                        ProcessName = g.Key ?? "未知工序",
                        TotalPlannedQuantity = g.Sum(x => x.PlannedQuantity ?? 0),
                        ProcessCount = g.Count()
                    })
                    .OrderByDescending(x => x.TotalPlannedQuantity)
                    .Take(5)
                    .ToList();

                return ApiResult<List<ProcessPlanRankDto>>.Success(processPlanRank);
            }
            catch (Exception ex)
            {
                return ApiResult<List<ProcessPlanRankDto>>.Error($"获取工序计划排名失败: {ex.Message}");
            }
        }

        /// <summary>
        /// 获取工序报工数Top5
        /// </summary>
        /// <param name="days">统计天数，默认30天</param>
        /// <returns>工序报工排名</returns>
        [HttpGet]
        public async Task<ApiResult<List<ProcessReportRankDto>>> GetProcessReportRank([FromQuery] int days = 30)
        {
            try
            {
                var startDate = DateTime.Now.AddDays(-days).Date;
                var endDate = DateTime.Now.Date.AddDays(1);

                // 从报工表统计工序报工数
                var processReportData = await _dbContext.WorkReport
                    .Where(wr => !wr.IsDeleted && wr.CreateTime >= startDate && wr.CreateTime < endDate)
                    .ToListAsync();

                var processReportRank = processReportData
                    .GroupBy(wr => wr.ProcessName)
                    .Select(g => new ProcessReportRankDto
                    {
                        ProcessName = g.Key,
                        TotalReportedQuantity = g.Sum(x => x.ReportQty),
                        ReportCount = g.Count()
                    })
                    .OrderByDescending(x => x.TotalReportedQuantity)
                    .Take(5)
                    .ToList();

                return ApiResult<List<ProcessReportRankDto>>.Success(processReportRank);
            }
            catch (Exception ex)
            {
                return ApiResult<List<ProcessReportRankDto>>.Error($"获取工序报工排名失败: {ex.Message}");
            }
        }

        /// <summary>
        /// 获取销售订单统计
        /// </summary>
        /// <param name="days">统计天数，默认30天</param>
        /// <returns>销售订单统计</returns>
        [HttpGet]
        public async Task<ApiResult<SalesOrderSummaryDto>> GetSalesOrderSummary([FromQuery] int days = 30)
        {
            try
            {
                var startDate = DateTime.Now.AddDays(-days).Date;
                var endDate = DateTime.Now.Date.AddDays(1);

                // 从销售订单表统计
                var salesOrders = await _dbContext.SalesOrder
                    .Where(so => !so.IsDeleted && so.CreateTime >= startDate && so.CreateTime < endDate)
                    .ToListAsync();

                var salesOrderProducts = await _dbContext.SalesOrderProduct
                    .Where(sop => !sop.IsDeleted && sop.CreateTime >= startDate && sop.CreateTime < endDate)
                    .ToListAsync();

                // 计算订单完成率（简化版本，假设有状态字段）
                var totalOrders = salesOrders.Count;
                var totalProducts = salesOrderProducts.Sum(sop => sop.Quantity);
                
                // 这里简化处理，实际应该根据业务逻辑计算完成率
                var orderCompletionRate = totalOrders > 0 ? 85.0m : 0; // 示例固定值

                var result = new SalesOrderSummaryDto
                {
                    TotalOrders = totalOrders,
                    TotalProducts = totalProducts,
                    OrderCompletionRate = orderCompletionRate
                };

                return ApiResult<SalesOrderSummaryDto>.Success(result);
            }
            catch (Exception ex)
            {
                return ApiResult<SalesOrderSummaryDto>.Error($"获取销售订单统计失败: {ex.Message}");
            }
        }

        /// <summary>
        /// 获取累计数据统计
        /// </summary>
        /// <returns>累计数据</returns>
        [HttpGet]
        public async Task<ApiResult<CumulativeDataDto>> GetCumulativeData()
        {
            try
            {
                // 累计单台数据（从产量统计表）
                var cumulativeUnitsData = await _dbContext.ProductionStatistics
                    .Where(ps => !ps.IsDeleted)
                    .SumAsync(ps => ps.Quantity);

                // 生产计划数据（从计划项目表）
                var productionPlanData = await _dbContext.PlanItemModel
                    .SumAsync(pi => pi.Quantity);

                // 累计合格数据（从工单表）
                var cumulativeQualifiedData = await _dbContext.WorkOrderModel
                    .SumAsync(wo => wo.GoodQuantity ?? 0);

                // 累计不合格数据（从工单表）
                var cumulativeUnqualifiedData = await _dbContext.WorkOrderModel
                    .SumAsync(wo => wo.BadQuantity ?? 0);

                var result = new CumulativeDataDto
                {
                    CumulativeUnitsData = cumulativeUnitsData,
                    ProductionPlanData = productionPlanData,
                    CumulativeQualifiedData = cumulativeQualifiedData,
                    CumulativeUnqualifiedData = cumulativeUnqualifiedData
                };

                return ApiResult<CumulativeDataDto>.Success(result);
            }
            catch (Exception ex)
            {
                return ApiResult<CumulativeDataDto>.Error($"获取累计数据统计失败: {ex.Message}");
            }
        }
    }

    #region DTO类定义

    /// <summary>
    /// 不良品率DTO
    /// </summary>
    public class DefectiveRateDto
    {
        /// <summary>
        /// 总不良品数
        /// </summary>
        public int TotalDefective { get; set; }

        /// <summary>
        /// 总生产数
        /// </summary>
        public int TotalProduced { get; set; }

        /// <summary>
        /// 不良品率（百分比）
        /// </summary>
        public decimal DefectiveRate { get; set; }

        /// <summary>
        /// 日期范围
        /// </summary>
        public string DateRange { get; set; }
    }

    /// <summary>
    /// 不良品项排名DTO
    /// </summary>
    public class DefectiveItemRankDto
    {
        /// <summary>
        /// 不良品项编号
        /// </summary>
        public string DefectiveItemCode { get; set; }

        /// <summary>
        /// 不良品项名称
        /// </summary>
        public string DefectiveItemName { get; set; }

        /// <summary>
        /// 总数量
        /// </summary>
        public int TotalQuantity { get; set; }

        /// <summary>
        /// 平均占比
        /// </summary>
        public decimal AvgPercentage { get; set; }
    }

    /// <summary>
    /// 员工绩效DTO
    /// </summary>
    public class EmployeePerformanceDto
    {
        /// <summary>
        /// 员工姓名
        /// </summary>
        public string EmployeeName { get; set; }

        /// <summary>
        /// 总良品数量
        /// </summary>
        public int TotalGoodQuantity { get; set; }

        /// <summary>
        /// 总工作时长（分钟）
        /// </summary>
        public int TotalWorkTime { get; set; }

        /// <summary>
        /// 报工次数
        /// </summary>
        public int ReportCount { get; set; }

        /// <summary>
        /// 效率分数
        /// </summary>
        public decimal EfficiencyScore { get; set; }
    }

    /// <summary>
    /// 生产汇总DTO
    /// </summary>
    public class ProductionSummaryDto
    {
        /// <summary>
        /// 总良品数量
        /// </summary>
        public int TotalGoodQuantity { get; set; }

        /// <summary>
        /// 总不良品数量
        /// </summary>
        public int TotalBadQuantity { get; set; }

        /// <summary>
        /// 良品率
        /// </summary>
        public decimal GoodRate { get; set; }

        /// <summary>
        /// 总工单数
        /// </summary>
        public int TotalWorkOrders { get; set; }
    }

    /// <summary>
    /// 日生产明细DTO
    /// </summary>
    public class DailyProductionDto
    {
        /// <summary>
        /// 生产日期
        /// </summary>
        public DateTime ProductionDate { get; set; }

        /// <summary>
        /// 产品名称
        /// </summary>
        public string ProductName { get; set; }

        /// <summary>
        /// 计划数量
        /// </summary>
        public int PlannedQuantity { get; set; }

        /// <summary>
        /// 良品数量
        /// </summary>
        public int GoodQuantity { get; set; }

        /// <summary>
        /// 不良品数量
        /// </summary>
        public int BadQuantity { get; set; }

        /// <summary>
        /// 完成率
        /// </summary>
        public decimal CompletionRate { get; set; }
    }

    /// <summary>
    /// 工序计划排名DTO
    /// </summary>
    public class ProcessPlanRankDto
    {
        /// <summary>
        /// 工序名称
        /// </summary>
        public string ProcessName { get; set; }

        /// <summary>
        /// 总计划数量
        /// </summary>
        public int TotalPlannedQuantity { get; set; }

        /// <summary>
        /// 工序数量
        /// </summary>
        public int ProcessCount { get; set; }
    }

    /// <summary>
    /// 工序报工排名DTO
    /// </summary>
    public class ProcessReportRankDto
    {
        /// <summary>
        /// 工序名称
        /// </summary>
        public string ProcessName { get; set; }

        /// <summary>
        /// 总报工数量
        /// </summary>
        public int TotalReportedQuantity { get; set; }

        /// <summary>
        /// 报工次数
        /// </summary>
        public int ReportCount { get; set; }
    }

    /// <summary>
    /// 销售订单汇总DTO
    /// </summary>
    public class SalesOrderSummaryDto
    {
        /// <summary>
        /// 总订单数
        /// </summary>
        public int TotalOrders { get; set; }

        /// <summary>
        /// 总产品数
        /// </summary>
        public int TotalProducts { get; set; }

        /// <summary>
        /// 订单完成率
        /// </summary>
        public decimal OrderCompletionRate { get; set; }
    }

    /// <summary>
    /// 累计数据DTO
    /// </summary>
    public class CumulativeDataDto
    {
        /// <summary>
        /// 累计单台数据
        /// </summary>
        public int CumulativeUnitsData { get; set; }

        /// <summary>
        /// 生产计划数据
        /// </summary>
        public int ProductionPlanData { get; set; }

        /// <summary>
        /// 累计合格数据
        /// </summary>
        public int CumulativeQualifiedData { get; set; }

        /// <summary>
        /// 累计不合格数据
        /// </summary>
        public int CumulativeUnqualifiedData { get; set; }
    }

    #endregion
} 